<?php 
/***
    Amrita ITEWS - Copyright (C) 2009 Amrita Vishwa Vidyapeetham, Amritapuri.
                                     (http://www.amrita.edu)
    ***************************************************************************
    This file is part of the Amrita ITEWS distribution.
    Amrita ITEWS is free software; you can redistribute it and/or modify it 
    under the terms of the GNU General Public License (version 2) as published 
    by the Free Software Foundation AND MODIFIED BY the Amrita ITEWS exception.
    ***NOTE*** The exception to the GPL is included to allow you to distribute
    a combined work that includes Amrita ITEWS without being obliged to provide
    the source code for proprietary components outside of the Amrita ITEWS
    software. Amrita ITEWS is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    Public License for more details. You should have received a copy of the GNU
    General Public License and the Amrita ITEWS license exception along with 
    Amrita ITEWS if not then it can be viewed here: 
    http://itews.amrita.ac.in/license.html.
    
    Documentation, latest information, license and contact details are at:
    http://itews.amrita.ac.in/
 
    Amrita ITEWS source code can be found at:
    http://code.google.com/p/itews"; 
    
    The initial code-base of Amrita ITEWS was developed by Amrita Vishwa 
    Vidyapeetham as part of the project titled,\"Intelligent & Interactive 
    Telematics using Emerging Wireless Technologies for Transport Systems 
    (ITEWS)\" sponsored by Technology Information Forecasting and Assessment 
    Council (TIFAC), India.
***/
?><?php
class NodesController extends AppController {

	var $name = 'Nodes';
	var $uses = array('Node', 'NodeInfo', 'NodeCode', 'RouteScheduleNodeAssoc', 'Trip', 'TripInfo');

	function index() {
		list($order, $limit, $page) = $this->setupPagination();
		$this->set('nodes', $this->Node->findAll(NULL, NULL, $order, $limit, $page));
	}

	function view($id = null) {
		$this->checkRecordExistance($id);
		$this->set('node', $this->Node->read(null, $id));
	}

	function add() {
		if(empty($this->data)) {
			if(!is_array($nodeTypes = $this->Node->NodeType->generateList(NULL, 'node_type_name ASC'))){
				$nodeTypes = array();
			}
			$this->set('nodeTypes', $nodeTypes);
			$this->render();
		} else {
			$this->cleanupData();
			$this->data['Node']['node_code'] = low($this->data['Node']['node_code']);
			if ($this->data['Node']['node_latitude_direction'] == 'N') {
				$this->data['Node']['node_latitude'] =  ($this->data['Node']['node_latitude']) ? '+' . $this->data['Node']['node_latitude'] : "";
			} else if ($this->data['Node']['node_latitude_direction'] == 'S') {
				$this->data['Node']['node_latitude'] =  ($this->data['Node']['node_latitude']) ? '-' . $this->data['Node']['node_latitude'] : "";
				 
			}
			if ($this->data['Node']['node_longitude_direction'] == 'E') {
				$this->data['Node']['node_longitude'] =  ($this->data['Node']['node_longitude']) ? '+' . $this->data['Node']['node_longitude'] : "";
			} else if ($this->data['Node']['node_longitude_direction'] == 'W') {
				$this->data['Node']['node_longitude'] =  ($this->data['Node']['node_longitude']) ? '-' . $this->data['Node']['node_longitude'] : "";
				 
			}
			if (!empty($this->data['Node']['node_area']) && !(strrchr($this->data['Node']['node_area'], ',') == ',')) {
				$this->data['Node']['node_area'] .= ','; 
			}
			$this->Node->begin();
			$this->NodeCode->begin();
			$this->NodeInfo->begin();
			$allowCommit = true;
			if($this->Node->save($this->data)) {
				$nodeId = $this->Node->getLastInsertID();
				$nodeCodeFields['NodeCode.node_code'] = $this->data['Node']['node_code'];
				if (!$this->NodeCode->hasAny($nodeCodeFields)) {
					$nodeCodeData['NodeCode']['node_id']   = $nodeId;
					$nodeCodeData['NodeCode']['node_code'] = $this->data['Node']['node_code'];
					if (!$this->NodeCode->save($nodeCodeData)) {
						$allowCommit = false;
						$this->Session->setFlash('Error while updating node code list.', 'message_error');
					}
				} else {
					$allowCommit = false;
					$this->Session->setFlash('Node code already exists in node codes list.', 'message_error');
				}
				if (!$this->pushToNodeInfoQueue('node', $nodeId)) {
					$allowCommit = false;
					$this->Session->setFlash('Error while updating node info table.', 'message_error');
				}
			} else {
				$allowCommit = false;
				$this->Session->setFlash('Please correct errors below.', 'message_error');
			}
			if ($allowCommit) {
				$this->Node->commit();
				$this->NodeCode->commit();
				$this->NodeInfo->commit();
				$this->Session->setFlash('New Node has been added.', 'message_ok');
				$this->redirect('/nodes/index');
			} else {
				$this->Node->rollback();
				$this->NodeCode->rollback();
				$this->NodeInfo->rollback();
				if(!is_array($nodeTypes = $this->Node->NodeType->generateList(NULL, 'node_type_name ASC'))){
					$nodeTypes = array();
				}
				$this->set('nodeTypes', $nodeTypes);
			}
			
		}
	}

	function edit($id = null) {
		if(empty($this->data)) {
			$this->checkRecordExistance($id);
			$this->data = $this->Node->read(null, $id);
			if(!is_array($nodeTypes = $this->Node->NodeType->generateList(NULL, 'node_type_name ASC'))){
				$nodeTypes = array();
			}
			$this->set('nodeTypes', $nodeTypes);
		} else {
			$this->cleanupData();
			$this->data['Node']['node_code'] = low($this->data['Node']['node_code']);
			if ($this->data['Node']['node_latitude_direction'] == 'N') {
				$this->data['Node']['node_latitude'] =  ($this->data['Node']['node_latitude']) ? '+' . $this->data['Node']['node_latitude'] : "";
			} else if ($this->data['Node']['node_latitude_direction'] == 'S') {
				$this->data['Node']['node_latitude'] =  ($this->data['Node']['node_latitude']) ? '-' . $this->data['Node']['node_latitude'] : "";
				 
			}
			if ($this->data['Node']['node_longitude_direction'] == 'E') {
				$this->data['Node']['node_longitude'] =  ($this->data['Node']['node_longitude']) ? '+' . $this->data['Node']['node_longitude'] : "";
			} else if ($this->data['Node']['node_longitude_direction'] == 'W') {
				$this->data['Node']['node_longitude'] =  ($this->data['Node']['node_longitude']) ? '-' . $this->data['Node']['node_longitude'] : "";
				 
			}
			if (!empty($this->data['Node']['node_area']) && !(strrchr($this->data['Node']['node_area'], ',') == ',')) {
				$this->data['Node']['node_area'] .= ','; 
			}
			$this->Node->begin();
			$this->NodeInfo->begin();
			if($this->Node->save($this->data)) {
				if ($this->pushToNodeInfoQueue('node', $id)) {
					$this->Node->commit();
					$this->NodeInfo->commit();
					$this->Session->setFlash('The Node has been saved.', 'message_ok');
					$this->redirect('/nodes/index');
				} else {
					$this->Node->rollback();
					$this->NodeInfo->rollback();
					$this->Session->setFlash('Please correct errors below.', 'message_error');
					if(!is_array($nodeTypes = $this->Node->NodeType->generateList(NULL, 'node_type_name ASC'))){
						$nodeTypes = array();
					}
					$this->set('nodeTypes', $nodeTypes);
				}
			} else {
				$this->Node->rollback();
				$this->NodeInfo->rollback();
				$this->Session->setFlash('Please correct errors below.', 'message_error');
				if(!is_array($nodeTypes = $this->Node->NodeType->generateList(NULL, 'node_type_name ASC'))){
					$nodeTypes = array();
				}
				$this->set('nodeTypes', $nodeTypes);
			}
		}
	}

	function delete($id = null, $confirm = null) {
		
		if ($confirm === null){
			$this->confirm_delete($id);
			exit(0);
		} else if ($confirm === 0) {
			$this->Session->setFlash('Operation cancelled by user.', 'message_ok');
			$this->redirect('/nodes/index');
			exit(0);
		} else {
			// Auto matic deletion with MySQl foreign key 
		}
		
		$this->checkRecordExistance($id);
		$this->Node->begin();
		$this->NodeCode->begin();
		$this->NodeInfo->begin();
		$this->TripInfo->begin();
		$allowCommit = true;
		if (!$this->reflectChangesInTripInfoQueue($id)) {
			$allowCommit = false;
			$this->Session->setFlash('Error while updating trip info queue, Node not deleted.', 'message_error');
		}
		if($this->Node->del($id)) {
			if (!$this->refreshNodeInfoQueue($id)) {
				$allowCommit = false;
				$this->Session->setFlash('Error while updating node info queue, Node not deleted.', 'message_error');
			}
			$nodeCodeListEntry = $this->NodeCode->find(array("NodeCode.node_id" => $id));
			$nodeCodeListEntry['NodeCode']['node_deleted'] = 1;
			if (!$this->NodeCode->save($nodeCodeListEntry)) {
				$allowCommit = false;
				$this->Session->setFlash('Error while updating node code list, Node not deleted.', 'message_error');
			}
			if ($allowCommit) {	
				$this->Node->commit();
				$this->NodeCode->commit();
				$this->NodeInfo->commit();
				$this->TripInfo->commit();
				$this->Session->setFlash('The Node deleted.', 'message_ok');
				$this->redirect('/nodes/index');
			} else {
				$this->Node->rollback();
				$this->NodeCode->rollback();
				$this->NodeInfo->rollback();
				$this->TripInfo->rollback();
				$this->redirect('/nodes/index');
			}
		} else {
			$this->Node->rollback();
			$this->NodeCode->rollback();
			$this->NodeInfo->rollback();
			$this->TripInfo->rollback();
			$this->showError(ERROR_DELETE, 'Unable to delete record.');
		}
	}
	
	function confirm_delete($id) {
		
		if (empty($this->data)) {
			$this->set('node_id', $id);
			$this->set('node_name', $this->Node->field('Node.node_name', "Node.id =".$id));
			$this->RouteSchedule->recursive = 5;
			if (!is_array($routeSchedules = $this->RouteScheduleNodeAssoc->findAll(array('Node.id' => $id)))) {
				$routeSchedules = array();
			}
			if (count($routeSchedules) == 0) {
				$this->delete($id, 1);
				exit(0);
			}		
			$this->set('routeSchedules', $routeSchedules);
			$this->render('confirm_delete');
			exit(0);
		} else {
			$this->checkJavaScript();
			if($this->data['Node']['confirm']){
				unset($this->data);
				$this->delete($id, 1);
				exit(0);
			} else {
				$this->delete($id, 1);
				exit(0);
			}
		}
		
	}
	
	function view_multiple($id = null) {
		$flag = true;
		if (isset($this->params['url']['ids'])) {
			$ids = explode(";", $this->params['url']['ids']);
			if (count($ids) > 0) {
				foreach ($ids as $id) {
					if ($id != null) {
						$id = intval($id); 
						unset($fields);
						$fields['Node.id'] = $id;
						if ($this->Node->hasAny($fields)) {
							$validIds[] = $id; 
						}
					} 
				}
				if (isset($validIds)) {
					$idList       = implode(",", $validIds);
					$conditions   = array("Node.id IN ($idList)");
					$nodes = $this->Node->findAll($conditions);
				} else {
					$flag = false;
				}
			} else {
				$flag = false;
			}
		} else {
			$flag = false;
		}
		if ($flag) {
			$this->set('nodes', $nodes);
		} else {
			$this->Session->setFlash('No Nodes selected to view.', 'message_error');
			$this->redirect('/nodes/index');
		}
	}
	
	/**
	 * Pushes a new entry to the node info queue 
	 * Do nothing if an entry with same info type and reference already exists
	 */
	function pushToNodeInfoQueue($infoType, $referenceId) {
		
		$fields['node_info_type'] = $infoType; 
		$fields['node_info_reference'] = $referenceId;
		if ($this->NodeInfo->hasAny($fields)) {
			// Entry already exists; Just return
			return true;
		}
		$data['NodeInfo']['id']                   = null;
		$data['NodeInfo']['node_info_type']      = $infoType;
		$data['NodeInfo']['node_info_reference'] = $referenceId;
		if ($this->NodeInfo->save($data)) {
			return true;
		} else {
			return false;
		}
		 
	}
	
	function refreshNodeInfoQueue($id) {
		
		$fields['NodeInfo.node_info_reference'] = $id;
		if ($this->NodeInfo->hasAny($fields)) {
			$nodeInfoId = $this->NodeInfo->field('NodeInfo.id', $fields);
			return $this->NodeInfo->del($nodeInfoId);
		} else {
			return $this->pushToNodeInfoQueue('node', $id);
		}
		
	}
	
	function reflectChangesInTripInfoQueue($id) {

		// Find all trips which uses this node
		
		$flag = true;
		
		$this->Trip->recursive=6;
		$trips = $this->Trip->findAll();
		$t = $this->Trip->findAll(array('Trip.id'=>28));
		foreach ($trips as $trip) {
			foreach ($trip['RouteSchedule']['Route']['RouteNodeAssoc'] as $rna) {
				if ($rna['Node']['id'] == $id) {
					if (!$this->refreshTripInfoQueue($trip['Trip']['id'], $trip['Trip']['vehicle_id'], $trip['Trip']['route_schedule_id'])) {
						$flag = false;
					}				
				}
			}
		}
		return $flag;
		
	}
	

	function refreshTripInfoQueue($tripId, $vehicleId, $routeScheduleId) {
		
		$fields['TripInfo.trip_info_reference'] = $tripId;
		if ($this->TripInfo->hasAny($fields)) {
			// Already exists, just return		
			return true;	
		} else {
			return $this->pushToTripInfoQueue($tripId, $vehicleId, $routeScheduleId);
		}
		
	}
	
	function pushToTripInfoQueue($tripId, $vehicleId, $routeScheduleId) {
		
		$field['trip_info_reference'] = $tripId;
		if($this->TripInfo->hasAny($field)) {
			return true;
		} else {
			$data['TripInfo']['trip_info_reference'] = $tripId;
			$data['TripInfo']['vehicle_id']          = $vehicleId;
			$data['TripInfo']['route_schedule_id']   = $routeScheduleId;
			return $this->TripInfo->save($data);
		}
		
	}

}
?>